﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using UmlDesigner.Model;
using UmlDesigner.Gui;

namespace UmlDesigner
{
    internal partial class NewMethodAttributeForm : Form
    {
        internal NewMethodAttributeForm(ClassWidget destClass)
        {
            InitializeComponent();
            Icon = Properties.Resources.ApplicationIcon;

            targetClass = destClass;
            workingClass = new ClassWidget();
            targetClass.ShallowCopyClassWidget(workingClass);

            foreach (UmlMethod m in workingClass.methods)
            {
                AddMethodToGui(m);
            }

            foreach (UmlDesigner.Model.Attribute a in workingClass.attributes)
            {
                AddAttrToGui(a);
            }

        }

        ClassWidget targetClass;
        ClassWidget workingClass;

        private void OnAddMethodClicked(object sender, EventArgs e)
        {
            UmlMethod method = new UmlMethod();
            NewMethodForm dlg = new NewMethodForm(method);
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                workingClass.methods.Add(method);
                AddMethodToGui(method);
            }
        }

        private void AddMethodToGui(UmlMethod method)
        {
            methodsDataGridView.Rows.Add(method.name, method.accessLevel, method.returnType, method.ArgsToString());
        }

        private void OnAddAttributeClicked(object sender, EventArgs e)
        {
            UmlDesigner.Model.Attribute attr = new UmlDesigner.Model.Attribute();
            NewAttributeForm dlg = new NewAttributeForm(attr);
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                workingClass.attributes.Add(attr);
                AddAttrToGui(attr);
            }
        }

        private void OnEditAttrClicked(object sender, EventArgs e)
        {
            if (attrsDataGridView.SelectedRows.Count == 0)
            {
                // Nothing selected.
                return;
            }

            UmlDesigner.Model.Attribute attr = GetSelectedAttr();

            NewAttributeForm dlg = new NewAttributeForm(attr);
            dlg.ShowDialog();

            // Update the grid control with the new data.
            DataGridViewRow row = attrsDataGridView.SelectedRows[0];
            row.Cells[0].Value = attr.name;
            row.Cells[1].Value = attr.accessLevel;
            row.Cells[2].Value = attr.type;
        }

        private void OnRemoveAttrClicked(object sender, EventArgs e)
        {
            if (attrsDataGridView.SelectedRows.Count == 0)
            {
                // Nothing selected.
                return;
            }

            workingClass.attributes.Remove(GetSelectedAttr());
            attrsDataGridView.Rows.Remove(attrsDataGridView.SelectedRows[0]);
        }

        private void AddAttrToGui(UmlDesigner.Model.Attribute attr)
        {
            attrsDataGridView.Rows.Add(attr.name, attr.accessLevel, attr.type);
        }

        private UmlDesigner.Model.Attribute GetSelectedAttr()
        {
            foreach (UmlDesigner.Model.Attribute a in workingClass.attributes)
            {
                DataGridViewRow row = attrsDataGridView.SelectedRows[0];

                if (a.name == (string)row.Cells[0].Value
                    && a.accessLevel == (string)row.Cells[1].Value
                    && a.type == (string)row.Cells[2].Value)
                {
                    return a;
                }
            }

            throw new Exception("Data inconsistancy error!");
        }

        private UmlMethod GetSelectedMethod()
        {
            foreach (UmlMethod m in workingClass.methods)
            {
                DataGridViewRow row = methodsDataGridView.SelectedRows[0];

                if (m.name == (string)row.Cells[0].Value
                    && m.accessLevel == (string)row.Cells[1].Value
                    && m.returnType == (string)row.Cells[2].Value
                    && m.ArgsToString() == (string)row.Cells[3].Value)
                {
                    return m;
                }
            }

            throw new Exception("Data inconsistancy error!");
        }

        private void OnEditMethodClicked(object sender, EventArgs e)
        {
            EditSelectedMethod();
        }

        private void EditSelectedMethod()
        {
            if (methodsDataGridView.SelectedRows.Count == 0)
            {
                // Nothing selected.
                return;
            }

            UmlMethod method = GetSelectedMethod();

            NewMethodForm dlg = new NewMethodForm(method);
            dlg.ShowDialog();

            // Update the grid control with the new data.
            DataGridViewRow row = methodsDataGridView.SelectedRows[0];
            row.Cells[0].Value = method.name;
            row.Cells[1].Value = method.accessLevel;
            row.Cells[2].Value = method.returnType;
            row.Cells[3].Value = method.ArgsToString();
        }

        private void OnRemoveMethodClicked(object sender, EventArgs e)
        {
            if (methodsDataGridView.SelectedRows.Count == 0)
            {
                // Nothing selected.
                return;
            }

            UmlMethod method = GetSelectedMethod();
            workingClass.methods.Remove(method);
            methodsDataGridView.Rows.Remove(methodsDataGridView.SelectedRows[0]);
        }

        private void OnOkClicked(object sender, EventArgs e)
        {
            workingClass.ShallowCopyClassWidget(targetClass);
        }

        private void methodsDataGridView_DoubleClick(object sender, EventArgs e)
        {
            EditSelectedMethod();
        }

    }
}
